package com.yourenbang.lingyun.transaction.web.controller.pay;

import cn.hutool.core.collection.CollectionUtil;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.yourenbang.lingyun.constants.AppId;
import com.yourenbang.lingyun.constants.BizCodeMessages;
import com.yourenbang.lingyun.constants.enums.pay.PayTypeEnum;
import com.yourenbang.lingyun.core.base.controller.BaseController;
import com.yourenbang.lingyun.core.base.interceptor.ExcludeInterceptor;
import com.yourenbang.lingyun.core.exception.BizRuntimeException;
import com.yourenbang.lingyun.core.message.Request;
import com.yourenbang.lingyun.core.message.Result;
import com.yourenbang.lingyun.core.util.KLog;
import com.yourenbang.lingyun.core.util.StringUtils;
import com.yourenbang.lingyun.core.util.http.RequestUtil;
import com.yourenbang.lingyun.mapper.AllyChannelMapper;
import com.yourenbang.lingyun.transaction.web.domain.dto.pay.PayTypeDTO;
import com.yourenbang.lingyun.transaction.web.domain.dto.pay.app.AppPayDTO;
import com.yourenbang.lingyun.transaction.web.domain.dto.pay.app.ToPupDTO;
import com.yourenbang.lingyun.transaction.web.domain.po.TSPayType;
import com.yourenbang.lingyun.transaction.web.domain.vo.pay.AppPayVO;
import com.yourenbang.lingyun.transaction.web.domain.vo.pay.ToPupVO;
import com.yourenbang.lingyun.transaction.web.service.pay.PayService;
import com.yourenbang.lingyun.transaction.web.service.pay.PayTypeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Objects;

/**
 * 支付方式
 */
@Slf4j
@RestController
@RequestMapping("/transaction/pay")
public class PayController extends BaseController {

    @Autowired
    private PayTypeService payTypeService;
    @Autowired
    private PayService payService;
    @Autowired
    AllyChannelMapper allyChannelMapper;


    /**
     * app获取支付方式
     *
     * @see <a href="https://huoyan.kaolakuaishou.cn/project/97/interface/api/4934">火眼接口连接</a>
     */
    @RequestMapping(value = "/paytype", method = RequestMethod.POST)
    Result<List<TSPayType>> payType(@Validated @RequestBody Request<PayTypeDTO> dto, BindingResult br) {
        KLog.info("[app获取支付方式]入参:{}", dto.toJSON());
        Result result = verifyParam(br);
        if (!result.isSuccess()) {
            return result;
        }
        PayTypeDTO payTypeDTO = dto.getData();
        List<TSPayType> payTypes = payTypeService.payType(payTypeDTO);
        //银小云屏蔽掉余额支付
        if (StringUtils.equalsAny(dto.getAppId(), AppId.YXY.getAppId(), AppId.YXY_MER.getAppId()) && CollectionUtil.isNotEmpty(payTypes)) {
            TSPayType balanceType = null;
            for (TSPayType payType : payTypes) {
                if (StringUtils.equals(payType.getCode(), PayTypeEnum.BALANCE.getCode())) {
                    balanceType = payType;
                }
            }
            if (Objects.nonNull(balanceType)) {
                payTypes.remove(balanceType);
            }
        }
        return Result.builder().success(payTypes);
    }

    /**
     * app获取支付方式V2 新版本使用的新接口，老版本会屏蔽掉余额支付
     *
     * @see <a href="https://huoyan.kaolakuaishou.cn/project/97/interface/api/4934">火眼接口连接</a>
     */
    @RequestMapping(value = "/paytype/v2", method = RequestMethod.POST)
    Result<List<TSPayType>> payTypeV2(@Validated @RequestBody Request<PayTypeDTO> dto, BindingResult br) {
        KLog.info("[app获取支付方式]入参:{}", dto.toJSON());
        Result result = verifyParam(br);
        if (!result.isSuccess()) {
            return result;
        }
        PayTypeDTO payTypeDTO = dto.getData();

        return Result.builder().success(payTypeService.payType(payTypeDTO));
    }

    /**
     * app支付
     *
     * @see <a href="https://huoyan.kaolakuaishou.cn/project/799/interface/api/15278">火眼接口连接</a>
     */
    @RequestMapping(value = "/app", method = RequestMethod.POST)
    public Result<AppPayVO> appPay(HttpServletRequest request, @Validated @RequestBody Request<AppPayDTO> dto, BindingResult br) {

        Result result = verifyParam(br);
        if (!result.isSuccess()) {
            return result;
        }

        try {
            AppPayDTO payDTO = dto.getData();
            payDTO.setIp(RequestUtil.ipAddress(request));
            AppPayVO payVO = payService.appPay(payDTO);

            KLog.info("【app支付】出参:{},入参:{}", payVO.toJSON(), dto.toJSON());

            return Result.builder().success(payVO);

        } catch (BizRuntimeException e) {

            KLog.warn("【app支付】BizRuntimeException异常,入参:{}", dto.toJSON(), e);
            return Result.builder().fail(BizCodeMessages.getBizCodeMessages(e.getErrorCode()));

        } catch (Exception e) {

            KLog.error("【app支付】异常,入参:{}", dto.toJSON(), e);
            return Result.builder().fail(BizCodeMessages.UNKNOWN_ERROR);

        }
    }

    /**
     * 充值
     *
     * @see <a href="https://huoyan.kaolakuaishou.cn/project/97/interface/api/6270">火眼接口连接</a>
     */
    @RequestMapping(value = "/topup", method = RequestMethod.POST)
    public Result<ToPupVO> createToPupOrder(@Validated @RequestBody Request<ToPupDTO> dto, BindingResult br) {
        KLog.info("【充值】入参:{}", dto.toJSON());
        Result result = verifyParam(br);
        if (!result.isSuccess()) {
            return result;
        }
        try {
            return Result.builder().success(payService.createToPupOrder(dto.getData()));
        } catch (BizRuntimeException e) {
            return Result.builder().fail(BizCodeMessages.getBizCodeMessages(e.getErrorCode()));
        } catch (Exception e) {
            return Result.builder().fail(BizCodeMessages.UNKNOWN_ERROR);
        }
    }

    /**
     * 微信app支付通知
     */
    @ExcludeInterceptor
    @RequestMapping(value = "/notice/wechat", method = RequestMethod.POST)
    public String wxNotice(@RequestBody String param) {
        KLog.info("【微信app支付通知】入参:{}", param);
        payService.wechatNotify(param);
        return WxPayNotifyResponse.success("成功");
    }

    /**
     * 阿里app支付通知
     */
    @ExcludeInterceptor
    @RequestMapping(value = "/notice/ali", method = RequestMethod.POST)
    public String aliNotice(HttpServletRequest request) {
        payService.aliNotify(request.getParameterMap());
        return "SUCCESS";
    }

}
